home *** CD-ROM | disk | FTP | other *** search
Wrap
/* * $Id: hclip.c,v 1.1.1.1 2000/04/07 19:44:51 hfrieden Exp $ * * $Date: 2000/04/07 19:44:51 $ * $Revision: 1.1.1.1 $ * * (C) 1999 by Hyperion * All rights reserved * * This file is part of the MiniGL library project * See the file Licence.txt for more details * */ static char rcsid[] = "$Id: hclip.c,v 1.1.1.1 2000/04/07 19:44:51 hfrieden Exp $"; #include "sysinc.h" #include <math.h> #include <stdio.h> //remove this #define CLIP_EPS (1e-7) #define DUMP_VERTEX(vert) \ mykprintf("x:%6.3f y:%6.3f z:%6.3f w:%6.3f\nR:%6.3f G:%6.3f B:%6.3f A:%6.3f\nU:%6.3f V:%6.3f\noutcode=0x%X\n",\ (vert).bx, (vert).by, (vert).bz, (vert).bw, \ (vert).v.color.r, (vert).v.color.g, (vert).v.color.b, (vert).v.color.a, \ (vert).v.u, (vert).v.v, (vert).outcode) #define LERP(t,a,b) \ ( (a) + (float)t * ( (b) - (a) ) ) #define x1 (a->bx) #define y1 (a->by) #define z1 (a->bz) #define w1 (a->bw) #define x2 (b->bx) #define y2 (b->by) #define z2 (b->bz) #define w2 (b->bw) #ifdef GLNDEBUG #define DEBUG_CLIP(name,code) code #else #define DEBUG_CLIP(name,code) \ mykprintf("%s: t=%f\n", #name, t);\ DUMP_VERTEX(*a); \ DUMP_VERTEX(*b); \ code \ DUMP_VERTEX(*r); #endif //multitexturing with virtual units:(real unit0 + 1 virt) /* Units are managed so unit0 is always first in line. Texture2D_State[1] is only set if there is any active units other than unit 0 If more than 1 hardware unit is present, the number of active virtual units should be reduced by 1. HW units should probably be implemented in a different manner. */ static void hc_ClipWZero(MGLVertex *a, MGLVertex *b, MGLVertex *r, GLenum shading) { float w; ULONG outcode; float t = (CLIP_EPS-w1)/(w2-w1); r->bx = LERP(t,a->bx, b->bx); r->by = LERP(t,a->by, b->by); r->bz = LERP(t,a->bz, b->bz); r->bw = CLIP_EPS; if(shading == GL_SMOOTH) { r->v.color.a = LERP(t,a->v.color.a, b->v.color.a); r->v.color.r = LERP(t,a->v.color.r, b->v.color.r); r->v.color.g = LERP(t,a->v.color.g, b->v.color.g); r->v.color.b = LERP(t,a->v.color.b, b->v.color.b); } r->v.u = LERP(t,a->v.u, b->v.u); r->v.v = LERP(t,a->v.v, b->v.v); if(mini_CurrentContext->Texture2D_State[1]) { r->tcoord.s = LERP(t,a->tcoord.s, b->tcoord.s); r->tcoord.t = LERP(t,a->tcoord.t, b->tcoord.t); } w = r->bw; outcode = 0; if (-w > r->bx) { outcode |= MGL_CLIP_LEFT; } else if (r->bx > w) { outcode |= MGL_CLIP_RIGHT; } if (-w > r->by) { outcode |= MGL_CLIP_BOTTOM; } else if (r->by > w) { outcode |= MGL_CLIP_TOP; } if (-w > r->bz) { outcode |= MGL_CLIP_BACK; } else if (r->bz > w) { outcode |= MGL_CLIP_FRONT; } r->outcode = outcode; if(mini_CurrentContext->CurrentTexQValid == GL_TRUE) { if (a->q == 1.0 && b->q == 1.0) r->q = 1.0; else r->q = CLIP_EPS; } } static void hc_ClipLeft(MGLVertex *a, MGLVertex *b, MGLVertex *r, GLenum shading) { float w; ULONG outcode; float t = (w1+x1)/((w1+x1)-(w2+x2)); r->by = LERP(t,a->by, b->by); r->bz = LERP(t,a->bz, b->bz); r->bw = LERP(t,a->bw, b->bw); r->bx = -r->bw; if(shading == GL_SMOOTH) { r->v.color.a = LERP(t,a->v.color.a, b->v.color.a); r->v.color.r = LERP(t,a->v.color.r, b->v.color.r); r->v.color.g = LERP(t,a->v.color.g, b->v.color.g); r->v.color.b = LERP(t,a->v.color.b, b->v.color.b); } r->v.u = LERP(t,a->v.u, b->v.u); r->v.v = LERP(t,a->v.v, b->v.v); if(mini_CurrentContext->Texture2D_State[1]) { r->tcoord.s = LERP(t,a->tcoord.s, b->tcoord.s); r->tcoord.t = LERP(t,a->tcoord.t, b->tcoord.t); } w = r->bw; outcode = 0; /* if (r->bw < CLIP_EPS ) { outcode |= MGL_CLIP_NEGW; } */ if (-w > r->by) { outcode |= MGL_CLIP_BOTTOM; } else if (r->by > w) { outcode |= MGL_CLIP_TOP; } if (-w > r->bz) { outcode |= MGL_CLIP_BACK; } else if (r->bz > w) { outcode |= MGL_CLIP_FRONT; } r->outcode = outcode; if(mini_CurrentContext->CurrentTexQValid == GL_TRUE) { r->q = LERP(t, a->q, b->q); } } static void hc_ClipRight(MGLVertex *a, MGLVertex *b, MGLVertex *r, GLenum shading) { float w; ULONG outcode; float t = (w1-x1)/((w1-x1)-(w2-x2)); r->by = LERP(t,a->by, b->by); r->bz = LERP(t,a->bz, b->bz); r->bw = LERP(t,a->bw, b->bw); r->bx = r->bw; if(shading == GL_SMOOTH) { r->v.color.a = LERP(t,a->v.color.a, b->v.color.a); r->v.color.r = LERP(t,a->v.color.r, b->v.color.r); r->v.color.g = LERP(t,a->v.color.g, b->v.color.g); r->v.color.b = LERP(t,a->v.color.b, b->v.color.b); } r->v.u = LERP(t,a->v.u, b->v.u); r->v.v = LERP(t,a->v.v, b->v.v); if(mini_CurrentContext->Texture2D_State[1]) { r->tcoord.s = LERP(t,a->tcoord.s, b->tcoord.s); r->tcoord.t = LERP(t,a->tcoord.t, b->tcoord.t); } w = r->bw; outcode = 0; /* if (r->bw < CLIP_EPS ) { outcode |= MGL_CLIP_NEGW; } */ if (-w > r->by) { outcode |= MGL_CLIP_BOTTOM; } else if (r->by > w) { outcode |= MGL_CLIP_TOP; } if (-w > r->bz) { outcode |= MGL_CLIP_BACK; } else if (r->bz > w) { outcode |= MGL_CLIP_FRONT; } r->outcode = outcode; if(mini_CurrentContext->CurrentTexQValid == GL_TRUE) { r->q = LERP(t, a->q, b->q); } } static void hc_ClipFront(MGLVertex *a, MGLVertex *b, MGLVertex *r, GLenum shading) { float w; ULONG outcode; float t = (w1-z1)/((w1-z1)-(w2-z2)); r->bx = LERP(t,a->bx, b->bx); r->by = LERP(t,a->by, b->by); r->bw = LERP(t,a->bw, b->bw); r->bz = r->bw; if(shading == GL_SMOOTH) { r->v.color.a = LERP(t,a->v.color.a, b->v.color.a); r->v.color.r = LERP(t,a->v.color.r, b->v.color.r); r->v.color.g = LERP(t,a->v.color.g, b->v.color.g); r->v.color.b = LERP(t,a->v.color.b, b->v.color.b); } r->v.u = LERP(t,a->v.u, b->v.u); r->v.v = LERP(t,a->v.v, b->v.v); if(mini_CurrentContext->Texture2D_State[1]) { r->tcoord.s = LERP(t,a->tcoord.s, b->tcoord.s); r->tcoord.t = LERP(t,a->tcoord.t, b->tcoord.t); } w = r->bw; outcode = 0; /* if (r->bw < CLIP_EPS ) { outcode |= MGL_CLIP_NEGW; } if (-w > r->bx) { outcode |= MGL_CLIP_LEFT; } else if (r->bx > w) { outcode |= MGL_CLIP_RIGHT; } */ if (-w > r->by) { outcode |= MGL_CLIP_BOTTOM; } else if (r->by > w) { outcode |= MGL_CLIP_TOP; } r->outcode = outcode; if(mini_CurrentContext->CurrentTexQValid == GL_TRUE) { r->q = LERP(t, a->q, b->q); } } static void hc_ClipBack(MGLVertex *a, MGLVertex *b, MGLVertex *r, GLenum shading) { float w; ULONG outcode; float t = (w1+z1)/((w1+z1)-(w2+z2)); r->bx = LERP(t,a->bx, b->bx); r->by = LERP(t,a->by, b->by); r->bw = LERP(t,a->bw, b->bw); r->bz = -r->bw; if(shading == GL_SMOOTH) { r->v.color.a = LERP(t,a->v.color.a, b->v.color.a); r->v.color.r = LERP(t,a->v.color.r, b->v.color.r); r->v.color.g = LERP(t,a->v.color.g, b->v.color.g); r->v.color.b = LERP(t,a->v.color.b, b->v.color.b); } r->v.u = LERP(t,a->v.u, b->v.u); r->v.v = LERP(t,a->v.v, b->v.v); if(mini_CurrentContext->Texture2D_State[1]) { r->tcoord.s = LERP(t,a->tcoord.s, b->tcoord.s); r->tcoord.t = LERP(t,a->tcoord.t, b->tcoord.t); } w = r->bw; outcode = 0; /* if (r->bw < CLIP_EPS ) { outcode |= MGL_CLIP_NEGW; } if (-w > r->bx) { outcode |= MGL_CLIP_LEFT; } else if (r->bx > w) { outcode |= MGL_CLIP_RIGHT; } */ if (-w > r->by) { outcode |= MGL_CLIP_BOTTOM; } else if (r->by > w) { outcode |= MGL_CLIP_TOP; } r->outcode = outcode; if(mini_CurrentContext->CurrentTexQValid == GL_TRUE) { r->q = LERP(t, a->q, b->q); } } static void hc_ClipTop(MGLVertex *a, MGLVertex *b, MGLVertex *r, GLenum shading) { float w; ULONG outcode; float t = (w1-y1)/((w1-y1)-(w2-y2)); r->bx = LERP(t,a->bx, b->bx); r->bz = LERP(t,a->bz, b->bz); r->bw = LERP(t,a->bw, b->bw); r->by = r->bw; if(shading == GL_SMOOTH) { r->v.color.a = LERP(t,a->v.color.a, b->v.color.a); r->v.color.r = LERP(t,a->v.color.r, b->v.color.r); r->v.color.g = LERP(t,a->v.color.g, b->v.color.g); r->v.color.b = LERP(t,a->v.color.b, b->v.color.b); } r->v.u = LERP(t,a->v.u, b->v.u); r->v.v = LERP(t,a->v.v, b->v.v); if(mini_CurrentContext->Texture2D_State[1]) { r->tcoord.s = LERP(t,a->tcoord.s, b->tcoord.s); r->tcoord.t = LERP(t,a->tcoord.t, b->tcoord.t); } /* Surgeon: this is always the 2nd last routine called, so here is no need to recode since a top-code means that there can be no bottom-code - we can safely set the outcode of the clipped vert to 0 */ #if 1 r->outcode = 0; #else w = r->bw; outcode = 0; if (r->bw < CLIP_EPS ) { outcode |= MGL_CLIP_NEGW; } if (-w > r->bx) { outcode |= MGL_CLIP_LEFT; } else if (r->bx > w) { outcode |= MGL_CLIP_RIGHT; } if (-w > r->bz) { outcode |= MGL_CLIP_BACK; } else if (r->bz > w) { outcode |= MGL_CLIP_FRONT; } r->outcode = outcode; #endif if(mini_CurrentContext->CurrentTexQValid == GL_TRUE) { r->q = LERP(t, a->q, b->q); } } static void hc_ClipBottom(MGLVertex *a, MGLVertex *b, MGLVertex *r, GLenum shading) { float w; ULONG outcode; float t = (w1+y1)/((w1+y1)-(w2+y2)); r->bx = LERP(t,a->bx, b->bx); r->bz = LERP(t,a->bz, b->bz); r->bw = LERP(t,a->bw, b->bw); r->by = -r->bw; if(shading == GL_SMOOTH) { r->v.color.a = LERP(t,a->v.color.a, b->v.color.a); r->v.color.r = LERP(t,a->v.color.r, b->v.color.r); r->v.color.g = LERP(t,a->v.color.g, b->v.color.g); r->v.color.b = LERP(t,a->v.color.b, b->v.color.b); } r->v.u = LERP(t,a->v.u, b->v.u); r->v.v = LERP(t,a->v.v, b->v.v); if(mini_CurrentContext->Texture2D_State[1]) { r->tcoord.s = LERP(t,a->tcoord.s, b->tcoord.s); r->tcoord.t = LERP(t,a->tcoord.t, b->tcoord.t); } /* Surgeon: this is always the last routine called, so here is no need to recode - we can safely set the outcode of the clipped vert to 0 */ #if 1 r->outcode = 0; #else w = r->bw; outcode = 0; if (r->bw < CLIP_EPS ) { outcode |= MGL_CLIP_NEGW; } if (-w > r->bx) { outcode |= MGL_CLIP_LEFT; } else if (r->bx > w) { outcode |= MGL_CLIP_RIGHT; } if (-w > r->bz) { outcode |= MGL_CLIP_BACK; } else if (r->bz > w) { outcode |= MGL_CLIP_FRONT; } r->outcode = outcode; #endif if(mini_CurrentContext->CurrentTexQValid == GL_TRUE) { r->q = LERP(t, a->q, b->q); } } #undef x1 #undef y1 #undef z1 #undef w1 #undef x2 #undef y2 #undef z2 #undef w2 GLboolean hc_DecideFrontface(GLcontext context, MGLVertex *a, MGLVertex *b, MGLVertex *c) { GLboolean front; float a1,a2,b1,b2,r; float aw,bw,cw; aw = 1.0 / a->bw; bw = 1.0 / b->bw; cw = 1.0 / c->bw; a1 = a->bx*aw - b->bx*bw; a2 = a->by*aw - b->by*bw; b1 = c->bx*cw - b->bx*bw; b2 = c->by*cw - b->by*bw; #define EPSILON (1e-5) #if 0 /* Surgeon: BUGFIX These expressions test the length of the triangle-sides in 3D space and is in essence a simple areatest - it should return GL_FALSE instead of GL_TRUE */ if (fabs(a1) < EPSILON && fabs(a2) < EPSILON) { return GL_TRUE; } if (fabs(b1) < EPSILON && fabs(b2) < EPSILON) { return GL_TRUE; } #else #if 0 //this test catches less than 1 in 1000 triangles so we disable it anyway if (fabs(a1) < EPSILON && fabs(a2) < EPSILON) { return GL_FALSE; } if (fabs(b1) < EPSILON && fabs(b2) < EPSILON) { return GL_FALSE; } #endif #endif r = a1*b2-a2*b1; if ((r < 0.0 && context->CurrentCullSign < 0) || (r > 0.0 && context->CurrentCullSign > 0)) { return GL_FALSE; } else { return GL_TRUE; } } void GLFrontFace(GLcontext context, GLenum mode) { int facing; GLint sign; if (mode == GL_CW || mode == GL_CCW) { context->CurrentFrontFace = mode; //Surgeon --> facing = (int)context->CurrentCullFace; switch(facing) { case GL_BACK: sign = 1; break; case GL_FRONT: sign = -1; break; default: sign = 0; break; } if(mode == GL_CW) { sign = -sign; } context->CurrentCullSign = sign; //Surgeon <-- } else { GLFlagError(context, 1, GL_INVALID_ENUM); } } void GLCullFace(GLcontext context, GLenum mode) { GLint sign; if (mode == GL_FRONT || mode == GL_FRONT_AND_BACK || mode == GL_BACK) { context->CurrentCullFace = mode; //Surgeon --> switch ((int)mode) { case GL_BACK: sign = 1; break; case GL_FRONT: sign = -1; break; default: sign = 0; break; } if(context->CurrentFrontFace == GL_CW) { sign = -sign; } context->CurrentCullSign = sign; //Surgeon <-- } else { GLFlagError(context, 1, GL_INVALID_ENUM); } } /* ** Complicated clipping macro stuff. */ #define VERTP(i) &(context->VertexBuffer[a->verts[i]]) #define VERT(i) ( context->VertexBuffer[a->verts[i]] ) #define OLD_POLYSWAP \ if (b->numverts == 0) return; \ temp=a; a=b; b=temp; \ #define POLYSWAP \ if (b->numverts == 0) {out->numverts = 0;return;} \ temp=a; a=b; b=temp; \ #define OLD_DOCLIP(edge, routine) \ if (or_codes & edge) \ { \ b->numverts = 0; \ prev = a->numverts-1; \ i=0; do \ { \ /* Case 1 and 4*/ \ if (!(VERT(prev).outcode & edge)) \ { \ b->verts[b->numverts] = a->verts[prev]; \ b->numverts++; \ } \ /* Case 3 and 4 */ \ if ((VERT(prev).outcode ^ VERT(i).outcode) & edge) \ { \ hc_##routine (VERTP(prev), VERTP(i), &(context->VertexBuffer[free]), (const GLenum)context->ShadeModel); \ b->verts[b->numverts]=free++; \ b->numverts++; \ } \ prev = i; \ } while (++i < a->numverts); \ OLD_POLYSWAP \ } #define DOCLIP(edge, routine) \ if (or_codes & edge) \ { \ b->numverts = 0; \ prev = a->numverts-1; \ i=0; do { \ /* Case 1 and 4*/ \ if (!(VERT(prev).outcode & edge)) \ { \ b->verts[b->numverts] = a->verts[prev]; \ b->numverts++; \ } \ /* Case 3 and 4 */ \ if ((VERT(prev).outcode ^ VERT(i).outcode) & edge) \ { \ hc_##routine (VERTP(prev), VERTP(i), &(context->VertexBuffer[free]), (const GLenum)context->ShadeModel); \ b->verts[b->numverts]=free++; \ b->numverts++; \ } \ prev = i; \ } while (++i < a->numverts); \ POLYSWAP \ } #ifndef GLNDEBUG void hc_DumpPolygon(GLcontext context, MGLPolygon *poly, char *string, int clipcode) { int i; mykprintf("--- %s (0x%X) -- (%d vertices)\n", string,clipcode, poly->numverts); for (i=0; i<poly->numverts; i++) { DUMP_VERTEX(context->VertexBuffer[poly->verts[i]]); } mykprintf("-------------------------\n"); } #define CLIPDBG(string,code) \ hc_DumpPolygon(context,a,#string,code); #else #define CLIPDBG(string,code) #endif void hc_ClipAndDrawPoly(GLcontext context, MGLPolygon *poly, ULONG or_codes) { /* ** Sutherland-Hodgeman clipping algorithm (almost) ** ** This clipping algorithm sucessively clips against each of the six ** clipping planes (additional client-defined clipping planes would ** be possible, those would be added to the back of this). ** Vertices are copied from a to b and swapped at the end. ** Output occurs within the clipping region: ** ** | b ** i|/| ** /| | ** / | |c ** a/ |/ ** | /|j ** |/ | ** d/ | ** |clip plane ** ** In the above figure, the algorithm first consideres edge d-a. Since it ** does not cross the clipping plane, it outputs d and proceeds to edge ** a-b. Since it crosses, it outputs a, calculates intersection i and outputs it. ** No output occurs while b-c is considered, since it lies outside the frustum ** and does not cross it. Finally, edge c-d yields output j. ** ** The result is d-a-i-j ** ** Classification of edges are divided into four cases: ** Case 1: Edge is completely inside -> two vertices ** Case 2: Edge is completely outside -> no output ** Case 3: Edge enters the frustum -> one output ** Case 4: Edge leaves frustum -> two outputs ** ** At any stage, if the output polygon has zero vertices, return immediately. */ MGLPolygon output; MGLPolygon *a, *b, *temp; int i,j; int prev; int free = context->VertexBufferPointer; GLboolean flag; ULONG original_or_codes = or_codes; a = poly; b=&output; CLIPDBG(ClipWZero, MGL_CLIP_NEGW) OLD_DOCLIP(MGL_CLIP_NEGW, ClipWZero); // Surgeon: conditioned by macro execution if(or_codes & MGL_CLIP_NEGW) { j = 0; do { or_codes |= context->VertexBuffer[a->verts[j]].outcode; j++; } while (j < a->numverts); } CLIPDBG(ClipLeft, MGL_CLIP_LEFT) OLD_DOCLIP(MGL_CLIP_LEFT, ClipLeft) CLIPDBG(ClipRight, MGL_CLIP_RIGHT) OLD_DOCLIP(MGL_CLIP_RIGHT, ClipRight) CLIPDBG(ClipFront, MGL_CLIP_FRONT) OLD_DOCLIP(MGL_CLIP_FRONT, ClipFront) CLIPDBG(ClipBack, MGL_CLIP_BACK) OLD_DOCLIP(MGL_CLIP_BACK, ClipBack) CLIPDBG(ClipTop, MGL_CLIP_TOP) OLD_DOCLIP(MGL_CLIP_TOP, ClipTop) CLIPDBG(ClipBottom, MGL_CLIP_BOTTOM) OLD_DOCLIP(MGL_CLIP_BOTTOM, ClipBottom) CLIPDBG(Final,0) // If we get here, there are vertices left... dh_DrawPoly(context, a); } void hc_ClipAndDrawLine(GLcontext context, MGLPolygon *poly, ULONG or_codes) { MGLPolygon output; MGLPolygon *a, *b, *temp; int i,j; int prev; int free = context->VertexBufferPointer; GLboolean flag; ULONG original_or_codes = or_codes; a = poly; b=&output; OLD_DOCLIP(MGL_CLIP_NEGW, ClipWZero); // Surgeon: conditioned by macro execution if(or_codes & MGL_CLIP_NEGW) { j = 0; do { or_codes |= context->VertexBuffer[a->verts[j]].outcode; j++; } while (j < a->numverts); } OLD_DOCLIP(MGL_CLIP_LEFT, ClipLeft) OLD_DOCLIP(MGL_CLIP_RIGHT, ClipRight) OLD_DOCLIP(MGL_CLIP_FRONT, ClipFront) OLD_DOCLIP(MGL_CLIP_BACK, ClipBack) OLD_DOCLIP(MGL_CLIP_TOP, ClipTop) OLD_DOCLIP(MGL_CLIP_BOTTOM, ClipBottom) dh_DrawLine(context,a); } //buffering: void hc_ClipPoly(GLcontext context, MGLPolygon *poly, PolyBuffer *out, int clipstart, ULONG or_codes) { MGLPolygon output; MGLPolygon *a, *b, *temp; int i,j; int prev; int free = clipstart; ULONG original_or_codes = or_codes; a = poly; b=&output; CLIPDBG(ClipWZero, MGL_CLIP_NEGW) DOCLIP(MGL_CLIP_NEGW, ClipWZero); // Surgeon: conditioned by macro execution if(or_codes & MGL_CLIP_NEGW) { j = 0; do { or_codes |= context->VertexBuffer[a->verts[j]].outcode; j++; } while (j < a->numverts); } CLIPDBG(ClipLeft, MGL_CLIP_LEFT) DOCLIP(MGL_CLIP_LEFT, ClipLeft) CLIPDBG(ClipRight, MGL_CLIP_RIGHT) DOCLIP(MGL_CLIP_RIGHT, ClipRight) CLIPDBG(ClipFront, MGL_CLIP_FRONT) DOCLIP(MGL_CLIP_FRONT, ClipFront) CLIPDBG(ClipBack, MGL_CLIP_BACK) DOCLIP(MGL_CLIP_BACK, ClipBack) CLIPDBG(ClipTop, MGL_CLIP_TOP) DOCLIP(MGL_CLIP_TOP, ClipTop) CLIPDBG(ClipBottom, MGL_CLIP_BOTTOM) DOCLIP(MGL_CLIP_BOTTOM, ClipBottom) CLIPDBG(Final,0) //write buffer index for(j=0; j<a->numverts; j++) out->verts[j] = a->verts[j]; out->numverts = a->numverts; out->nextfree = free; } void hc_ClipPolyFF(GLcontext context, MGLPolygon *poly, ULONG or_codes) { MGLPolygon *out; MGLPolygon output; MGLPolygon *a, *b, *temp; int i,j; int prev; int free = context->VertexBufferPointer; a = poly; b=&output; out = poly; CLIPDBG(ClipWZero, MGL_CLIP_NEGW) DOCLIP(MGL_CLIP_NEGW, ClipWZero); // Surgeon: conditioned by macro execution if(or_codes & MGL_CLIP_NEGW) { j = 0; do { or_codes |= context->VertexBuffer[a->verts[j]].outcode; j++; } while (j < a->numverts); } CLIPDBG(ClipLeft, MGL_CLIP_LEFT) DOCLIP(MGL_CLIP_LEFT, ClipLeft) CLIPDBG(ClipRight, MGL_CLIP_RIGHT) DOCLIP(MGL_CLIP_RIGHT, ClipRight) CLIPDBG(ClipFront, MGL_CLIP_FRONT) DOCLIP(MGL_CLIP_FRONT, ClipFront) CLIPDBG(ClipBack, MGL_CLIP_BACK) DOCLIP(MGL_CLIP_BACK, ClipBack) CLIPDBG(ClipTop, MGL_CLIP_TOP) DOCLIP(MGL_CLIP_TOP, ClipTop) CLIPDBG(ClipBottom, MGL_CLIP_BOTTOM) DOCLIP(MGL_CLIP_BOTTOM, ClipBottom) CLIPDBG(Final,0) //write buffer index for(j=0; j<a->numverts; j++) poly->verts[j] = a->verts[j]; poly->numverts = a->numverts; }